/**
 * Alipay.com Inc.
 * Copyright (c) 2004-2012 All Rights Reserved.
 */
package com.example.togethermove.utils.rsa;

import android.text.TextUtils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringWriter;
import java.security.KeyFactory;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;

import javax.crypto.Cipher;


/**
 * 
 * @author runzhi
 */
public class Signature {

    /** RSA最大加密明文大小  */
    private static final int MAX_ENCRYPT_BLOCK = 117;

    /** RSA最大解密密文大小   */
    private static final int MAX_DECRYPT_BLOCK = 128;

    public static final String md5key="RongXin";
    public static final String rsakey="MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCojpk5L9yE3qLcnzRFjbBaoWt83zE8Njg1XigQwexiNRMy8d9TUdMMpywX432iiqocTnLWBaD9XVctdswiyNUVac6EBPnwzCsmKwacnJswCywvPmXFvUZm/F3aIxRu4szD6g3pUsi7bGFKHYCi3AOi7bzhoPpjWPDlnD3191jssQIDAQAB";
//    public static native String getRsaKey();
//    public static native String getMd5Key();
//    public static native String getWechatId();
    static {
//        System.loadLibrary("native-lib");
    }


    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
                                                    InputStream ins) throws Exception {
        if (ins == null || TextUtils.isEmpty(algorithm)) {
            return null;
        }

        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);

        byte[] encodedKey = StreamUtil.readText(ins).getBytes();

        encodedKey = Base64.decodeBase64(encodedKey);

        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }



    public static PublicKey getPublicKeyFromX509(String algorithm,
                                                 InputStream ins) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);

        StringWriter writer = new StringWriter();
        StreamUtil.io(new InputStreamReader(ins), writer);

        byte[] encodedKey = writer.toString().getBytes();

        encodedKey = Base64.decodeBase64(encodedKey);

        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }


    public static String rsaEncode(String content){
        try {
//            return rsaEncrypt(content,public_key,"utf-8");
            return rsaEncrypt(content,rsakey,"utf-8");
        }catch (Exception e){
            return "";
        }

    }

    /**
     * 公钥加密
     * 
     * @param content   待加密内容
     * @param publicKey 公钥
     * @param charset   字符集，如UTF-8, GBK, GB2312
     * @return 密文内容
     * @throws AlipayApiException
     */
    public static String rsaEncrypt(String content, String publicKey,
                                    String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509(AlipayConstants.SIGN_TYPE_RSA,
                new ByteArrayInputStream(publicKey.getBytes()));
//            Cipher cipher = Cipher.getInstance(AlipayConstants.SIGN_TYPE_RSA);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.ENCRYPT_MODE, pubKey);
            byte[] data = TextUtils.isEmpty(charset) ? content.getBytes()
                : content.getBytes(charset);
            int inputLen = data.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段加密  
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_ENCRYPT_BLOCK) {
                    cache = cipher.doFinal(data, offSet, MAX_ENCRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(data, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_ENCRYPT_BLOCK;
            }
            byte[] encryptedData = Base64.encodeBase64(out.toByteArray());
            out.close();

            return TextUtils.isEmpty(charset) ? new String(encryptedData)
                : new String(encryptedData, charset);
        } catch (Exception e) {
            throw new Exception("EncryptContent = " + content + ",charset = " + charset,
                e);
        }
    }

    public static String rsaDecrypt(String content) throws Exception {
        return rsaDecryptPublicKey(content,rsakey,"UTF-8");
//        return rsaDecryptPublicKey(content,getRsaKey(),"UTF-8");
    }



    /**
     * 私钥解密
     * 
     * @param content    待解密内容
     * @param publicKey 私钥
     * @param charset    字符集，如UTF-8, GBK, GB2312
     * @return 明文内容
     * @throws Exception
     * @throws AlipayApiException
     */
    public static String rsaDecryptPublicKey(String content, String publicKey,
                                             String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509(AlipayConstants.SIGN_TYPE_RSA,
                    new ByteArrayInputStream(publicKey.getBytes()));
//            Cipher cipher = Cipher.getInstance(AlipayConstants.SIGN_TYPE_RSA);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, pubKey);
            byte[] encryptedData = TextUtils.isEmpty(charset)
                ? Base64.decodeBase64(content.getBytes())
                : Base64.decodeBase64(content.getBytes(charset));
            int inputLen = encryptedData.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密  
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();

            return TextUtils.isEmpty(charset) ? new String(decryptedData)
                : new String(decryptedData, charset);
        } catch (Exception e) {
            throw new Exception("EncodeContent = " + content + ",charset = " + charset, e);
        }
    }

    public static String rsaDecryptPrivateKey(String content, String privateKey,
                                              String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8(AlipayConstants.SIGN_TYPE_RSA,
                new ByteArrayInputStream(privateKey.getBytes()));
//            Cipher cipher = Cipher.getInstance(AlipayConstants.SIGN_TYPE_RSA);
            Cipher cipher = Cipher.getInstance("RSA/ECB/PKCS1Padding");
            cipher.init(Cipher.DECRYPT_MODE, priKey);
            byte[] encryptedData = TextUtils.isEmpty(charset)
                    ? Base64.decodeBase64(content.getBytes())
                    : Base64.decodeBase64(content.getBytes(charset));
            int inputLen = encryptedData.length;
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            int offSet = 0;
            byte[] cache;
            int i = 0;
            // 对数据分段解密
            while (inputLen - offSet > 0) {
                if (inputLen - offSet > MAX_DECRYPT_BLOCK) {
                    cache = cipher.doFinal(encryptedData, offSet, MAX_DECRYPT_BLOCK);
                } else {
                    cache = cipher.doFinal(encryptedData, offSet, inputLen - offSet);
                }
                out.write(cache, 0, cache.length);
                i++;
                offSet = i * MAX_DECRYPT_BLOCK;
            }
            byte[] decryptedData = out.toByteArray();
            out.close();

            return TextUtils.isEmpty(charset) ? new String(decryptedData)
                    : new String(decryptedData, charset);
        } catch (Exception e) {
            throw new Exception("EncodeContent = " + content + ",charset = " + charset, e);
        }
    }

    public static void main(String[] args) throws Exception {
//    	try {
//
//    		MessageRsa rsa = new MessageRsa();
//
//    		rsa.setMsg_Json_Body("{'data':8965490}");
//    		String noetStr = RandomStringGenerator.getRandomStringByLength(32);
//    		rsa.setNoteStr(noetStr);
//    		rsa.setReceiver_Sys("app");
//    		rsa.setRecord_No("10987654321");
//    		rsa.setServer_Code("899933");
//
//    		rsa.setSign_Data(MD5.getMD5Str("10987654321app456789{'data':8965490}201233333333"+noetStr+key));
//    		rsa.setTimeStr("201233333333");
//
//			String rsa_1 = rsaEncrypt(JSONUtil.toJSonString(rsa),public_key,"utf-8");
//
//    		System.out.println(rsa_1);
//    		String rsa_2=rsaDecrypt(rsa_1,private_key,"utf-8");
//			System.out.println(rsa_2);
//
//		} catch (AlipayApiException e) {
//			e.printStackTrace();
//		}
	}
}
